package com.netty.utils;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mongodb.*;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import com.mongodb.util.JSON;
import com.netty.utils.PageUtils;
import org.bson.BsonDocument;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 * mongodb工具类
 *
 * @author gjj
 */
public class MongoDbUtil {

    private Logger mongoLogger = Logger.getLogger( "org.mongodb.driver" );


    private MongoClient mongoClient;

    private MongoDatabase mongoDatabase;

    public MongoDbUtil() {
        mongoLogger.setLevel(Level.SEVERE);
        MongoClientOptions.Builder build = new MongoClientOptions.Builder();
        MongoClientOptions options = build.build();
        // 连接到 mongodb 服务
        List<ServerAddress> addrs = new ArrayList<ServerAddress>();
        ServerAddress serverAddress = new ServerAddress(Constants.MONGODB_HOST,
                Constants.MONGODB_PORT);
        addrs.add(serverAddress);
        MongoCredential credential = MongoCredential.createScramSha1Credential(Constants.MONGODB_USER, Constants.MONGODB_DATABASE,
                Constants.MONGODB_PWD.toCharArray());
        List<MongoCredential> credentials = new ArrayList<MongoCredential>();
        credentials.add(credential);
        mongoClient = new MongoClient(addrs, credentials, options);
        // 连接到数据库
        mongoDatabase = mongoClient.getDatabase(Constants.MONGODB_DATABASE);
    }

    public void close(){
        mongoClient.close();
    }

    public void insertDocument(Document document, String collectionName) {
        MongoCollection<Document> collection = mongoDatabase.getCollection(collectionName);
        collection.insertOne(document);
    }

    public void updateDocument(Bson bson, Bson newBson, String collectionName){
        MongoCollection<Document> collection = mongoDatabase.getCollection(collectionName);
        collection.updateOne(bson,newBson);
    }


    public HashMap<String,Object> queryByID(String collectionName, Object Id)  {
        MongoCollection<Document> collection = mongoDatabase.getCollection(collectionName);
        BasicDBObject query = new BasicDBObject("_id", Id);
        //  DBObject接口和BasicDBObject对象：表示一个具体的记录，BasicDBObject实现了DBObject，是key-value的数据结构，用起来和HashMap是基本一致的。
        FindIterable<Document> iterable = collection.find(query);

        HashMap<String,Object> jsonStrToMap = null;
        MongoCursor<Document> cursor = iterable.iterator();
        while (cursor.hasNext()) {
            Document user = cursor.next();
            String jsonString = user.toJson();
            jsonStrToMap = jsonStrToMap(jsonString);
        }

        return jsonStrToMap;
    }

    public HashMap<String, Object> jsonStrToMap(String jsonString) {
        ObjectMapper objectMapper=new ObjectMapper();
        Object parseObj = null;
        try {
            parseObj = objectMapper.readValue(jsonString, Object.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        HashMap<String, Object> map = (HashMap<String, Object>) parseObj; // 把对象转化为map
        return map;
    }

    public PageUtils queryPage(String collectionName,BasicDBObject doc,
                               Integer page,Integer pageSize,BasicDBObject sort){
        MongoCollection<Document> collection = mongoDatabase.getCollection(collectionName);
        FindIterable<Document> iterable = collection.find(doc).sort(sort).skip((page-1)*pageSize).limit(pageSize);
        Long total = collection.countDocuments(doc);
        List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
        MongoCursor<Document> cursor = iterable.iterator();
        while (cursor.hasNext()) {
            Document user = cursor.next();
            String jsonString = user.toJson();
            Map<String, Object> jsonStrToMap = jsonStrToMap(jsonString);
            list.add(jsonStrToMap);
        }
        return new PageUtils(list,total.intValue());
    }

    public List<Map<String,Object>> queryByDoc(String collectionName, BasicDBObject doc) {
        MongoCollection<Document> collection = mongoDatabase.getCollection(collectionName);
        FindIterable<Document> iterable = collection.find(doc);
        List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
        MongoCursor<Document> cursor = iterable.iterator();
        while (cursor.hasNext()) {
            Document user = cursor.next();
            String jsonString = user.toJson();
            Map<String, Object> jsonStrToMap = jsonStrToMap(jsonString);
            list.add(jsonStrToMap);
        }
        return list;
    }
    public void deleteById(Object id,String collectionName){
        MongoCollection<Document> collection = mongoDatabase.getCollection(collectionName);
        BasicDBObject query = new BasicDBObject("_id", id);
        collection.deleteOne(query);
    }

    public void deleteByMap(BasicDBObject query,String collectionName){
        MongoCollection<Document> collection = mongoDatabase.getCollection(collectionName);
        collection.deleteOne(query);
    }

}